/*
gulp 程序说明

gulp.src()
    gulp自带的函数程序
    作用是 读取 指定文件夹中文件的内容
        *.css   文件名可以是任意文件名 扩展名必须是css的文件

        *.*     文件名是任意名称 扩展名是任意名称的文件 也就是 所有文件

        **      读取所有的文件和文件夹

pipe()
    gulp自带的函数程序
    和 gulp.src() 语法配合使用
    对 gulp.src()语法 读取的文件内容 执行操作
    也就是 对 gulp.src() 读取的文件内容 执行 打包压缩规范

gulp.dest()
    gulp自带的函数程序
    作用是 将 gulp.src() 读取的文件内容 执行打包压缩之后 
    存储到 指定的路径位置 
    如果没有指定的文件 创建 这个文件 执行写入操作

gulp.watch( 参数1 , 参数2 )
    gulp自带的函数程序
    参数1   要监听的文件 
    参数2   监听文件内容改变 触发执行的打包压缩规范 名称


module.exports.default
    gulp 模块 导出 默认程序的固定语法形式
    相当于 以 对象的形式导出 
    属性是 default

gulp.series()
    gulp自带的函数程序
    参数是 多个 函数名称 或者 特殊的执行函数
    是 按照 顺序 一个一个 触发执行 设定的函数

gulp.parallel()
    gulp自带的函数程序
    参数是 多个 函数名称 或者 特殊的执行函数
    是 同时 触发执行 设定的函数




*/



//  gulp语法规范规定的配置文件名称 在这个文件中 定义 gulp程序

//  一 导入 依赖包

// 导入 gulp 依赖包
const gulp = require('gulp');

// 导入 css 依赖包
const autoprefixer = require('gulp-autoprefixer');
const cssmin = require('gulp-cssmin');

// 导入 js依赖包
// 下载了 4个依赖包 只需要导入 2个依赖包 
const babel = require('gulp-babel');
const uglify = require('gulp-uglify');

// 导入 html依赖包
const htmlmin = require('gulp-htmlmin');

// 导入 sass依赖包 
// 导入 sass依赖包 语法特殊 需要 同时导入 两个依赖包 
// 先 导入 gulp-sass 再 导入 sass
const sass= require('gulp-sass')( require('sass') );

// 导入 服务器依赖
const webserver = require('gulp-webserver');

// 删除 依赖包
const del = require('del');

//  二 设定 打包规范

//  2-1 需要 打包压缩的文件

//  2-1-1 css打包压缩规范
//  赋值式函数语法 定义 打包压缩规范
const cssHandler = function(){
    // 必须是 以 return 的形式 设定程序 
    // 可以使用链式编程语法定义程序
    return gulp.src('./src/css/*.css')          //  读取文件内容
           .pipe( autoprefixer() )              //  对 gulp.src() 读取的文件 添加 前缀
           .pipe( cssmin() )                    //  继续 对  gulp.src() 读取的文件 压缩 css文件
           .pipe( gulp.dest('./dist/css') );    //  续集 对 添加前缀 压缩好的文件内容 指定存储位置 
}

//  2-1-2 js打包压缩规范
const jsHandler = function(){
    // 必须是 以 return 的形式 设定程序 
    // 可以使用链式编程语法定义程序
    return gulp.src('./src/js/*.js')          
           .pipe( babel( {presets:['@babel/env']} ) )    //  其他格式js程序 转化为 ES5语法格式
           .pipe( uglify() )                    //  将 ES5语法格式 js程序 打包压缩
           .pipe( gulp.dest('./dist/js') );    
           //   特别注意 带有 promise 的程序 必须要 配合polyfill.js 文件执行
}

//  2-1-3 html打包压缩规范
const htmlHandler = function(){
    // 必须是 以 return 的形式 设定程序 
    // 可以使用链式编程语法定义程序
    return gulp.src('./src/pages/*.html')          
           .pipe( htmlmin({     // 以对象的形式设定html压缩的配置参数
            removeAttributeQuotes:true,     //  删除属性中的双引号
            removeComments:true,            //  删除注释
            removeEmptyAttributes:true,     //  删除空属性
            // removeEmptyElements:true,       //  删除空标签
            removeScriptTypeAttributes:true,    //  script标签删除type属性 但是 三阶段模块化开发 需要 type属性
            removeStyleLinkTypeAttributes:true, //  style标签link删除type属性
            collapseBooleanAttributes:true,     //  删除布尔属性的属性值
            collapseWhitespace:true,            //  删除标签之间的空格
            minifyCSS:true,                     //  压缩 内部css样式代码
            minifyJS:true,                      //  压缩 内部js样式代码 一般压缩都会压缩报错


           })) 
           .pipe( gulp.dest('./dist/html') );    

}


// 2-1-4 sass打包压缩规范
// 先 将 sass / scss 文件转化为 css文件 
// 在 按照 css文件规范 压缩转化的css文件
// 实际项目中 一般 不会 有 sass 和 css 同时存在的情况
// const sassHandler = function(){
//     // 必须是 以 return 的形式 设定程序 
//     // 可以使用链式编程语法定义程序
//     return gulp.src('./src/scss/*.scss')        //  读取文件内容
//            .pipe( sass() )                      //  按照 sass语法 将 读取的sass文件内容 转化为 css文件格式
//            .pipe( autoprefixer() )              //  对 gulp.src() 读取的文件 添加 前缀
//            .pipe( cssmin() )                    //  继续 对  gulp.src() 读取的文件 压缩 css文件
//            .pipe( gulp.dest('./dist/css') );    //  续集 对 添加前缀 压缩好的文件内容 指定存储位置 
// }


//  2-2 不需要 打包压缩的文件
//  读取文件内容 直接 存储到 指定的文件夹中

//  图片的打包压缩规范
const imgHandler = function(){
    return gulp.src( './src/images/*.*' ).pipe( gulp.dest('./dist/images') );
}


//  server的打包压缩规范
const phpHandler = function(){
    return gulp.src( './src/server/*.php' ).pipe( gulp.dest('./dist/server') );
}

//  工具的打包压缩规范
const toolsHandler = function(){
    return gulp.src( './src/tools/**' ).pipe( gulp.dest('./dist/tools') );
}

// font压缩
const fontsHandler = function(){
    return gulp.src( './src/fonts/**' ).pipe( gulp.dest('./dist/fonts') );
}



//  三 删除程序
/*
gulp打包压缩 只有 读取 --- 压缩 --- 存储 步骤 
没有 删除 步骤 
如果 原始文件 删除了 某个文件 在 执行 gulp打包压缩程序时
默认 没有 删除 对应文件的步骤
需要 独立设定一个 删除程序 
在 执行新的压缩之前 先 删除所有原始压缩文件
只 保留 新压缩的结果 也就是 最新原始文件 对应的 压缩文件
*/

const delHandler = function(){
    return del([ './dist' ]);
}



//  四 监听程序
const watchHandler = function(){
    gulp.watch( './src/css/*.css' , cssHandler );
    gulp.watch( './src/js/*.js' , jsHandler );
    gulp.watch( './src/pages/*.html' , htmlHandler );
    // gulp.watch( './src/scss/*.scss' , sassHandler );
    gulp.watch( './src/message/*.*' , imgHandler );
    gulp.watch( './src/server/*.php' , phpHandler );
    gulp.watch( './src/tool/**' , toolsHandler );
    gulp.watch( './src/font/**' , fontsHandler );

}


//  五 服务器规范
//  主要演示 服务器 热启动 
//  所谓的 服务器热启动 是 服务器的一项功能 
//  当 服务器 根目录中 文件内容改变 服务器自动 刷新显示内容
// const webserverHandler = function(){
//     return gulp.src('./dist')
//            .pipe( webserver({       // 以对象的形式 配置 服务器参数
//                 host:'127.0.0.1',
//                 port:'8088',
//                 open:'./pages/index.html',
//                 livereload:true,    // 开启 热启动
//            }))
// }


//  六 设定 gulp 导出的默认程序
//  设定了导出默认程序 之后 再执行gulp程序 
//  直接 在 命令行中 输入 gulp 就可以了 
module.exports.default = gulp.series(
    // 这里定义的函数 会 按照顺序 一个一个的执行 

    // 先 执行删除操作
    delHandler , 

    // 再执行 打包压缩操作
    gulp.parallel( cssHandler , jsHandler , htmlHandler , imgHandler , phpHandler , toolsHandler ,fontsHandler),

    // 执行 服务器规范
    // webserverHandler,

    // 再执行 监听操作
    watchHandler

)



